#!/usr/bin/env python

#
# sync script
#
# Copyright 2006-2007 Helsinki Institute for Information Technology
# and the authors.
#
# Authors: Ken Rimey <rimey@hiit.fi>
#

# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

import time
from Queue import Queue, Empty

import pathhack
from fusion.db.sqlite_db import SqliteDB
from fusion.db.util import get_default_path
from messkit.threaded_stream import StreamManager
from fusion.sync.sync_manager import SyncManager

def main(path, host, port, continuous, polling_interval=0.1):
    def sync_complete():
        if not continuous:
            session.close()

    def session_closed():
        session.shutdown()
        stream_mgr.close(mgr_closed)

    def mgr_closed():
        queue.put(None)

    db = SqliteDB(path)
    try:
        queue = Queue()
        stream_mgr = StreamManager(queue.put)
        sync_mgr = SyncManager(db, stream_mgr)
        session = sync_mgr.connect((host, port),
                                   sync_complete = sync_complete,
                                   shutdown = session_closed)

        next_update = time.time() + polling_interval
        while True:
            try:
                remaining = next_update - time.time()
                if remaining > 0:
                    f = queue.get(timeout=remaining)
                    if not f:
                        break
                    f()
                else:
                    session.update()
                    next_update = time.time() + polling_interval
            except Empty:
                pass
            except KeyboardInterrupt:
                session.close()
    finally:
        db.close()
        print 'Exiting...'

if __name__ == '__main__':
    from optparse import OptionParser

    parser = OptionParser()

    path = get_default_path()
    parser.add_option('--db', dest='path', default=path,
                      help='location of database (default is %s)' % path)
    parser.add_option('--host', default='localhost',
                      help='host to connect to (default is localhost)')
    parser.add_option('--port', type='int', default=35800,
                      help='port to connect to (default is 35800)')
    parser.add_option('--once', action='store_false',
                      dest='continuous', default=True,
                      help='whether to exit after initial sync')

    options, args = parser.parse_args()
    if args:
        parser.error('incorrect number of arguments')

    main(path=options.path,
         host=options.host,
         port=options.port,
         continuous=options.continuous)
